import { message } from 'antd';
import axios from 'axios';
import { ForbiddenException } from './errors/forbidden';
import { ServerErrorException } from './errors/server-error';

export * from './errors/server-error';

// 设置请求前缀
const API_PREFIX = '/admin-api/';
const http = axios.create({
  // baseURL: API_PREFIX,
  timeout: 300000,
});

http.interceptors.request.use((config) => {
  const token = localStorage.getItem('Authorization');
  if (token) {
    config.headers['Authorization'] = token;
  }
  return config;
});

http.interceptors.response.use(
  (response) => {
    const { data } = response;

    // 根据后端请求结构，如果code不为200，则认为是异常
    if (data?.code !== 200) {
      // 抛出服务器异常，并且携带response
      message.error(data?.message);

      return Promise.reject(new ServerErrorException(data.message, response));
    }

    return data?.result || data?.data;
  },
  (error) => {
    message.error(error.response?.data?.message || error.response?.data?.error || '请求失败');

    if (error.response.status === 401) {
      window.location.pathname = '/login';
    }

    if (error.response.status === 403) {
      return Promise.reject(new ForbiddenException());
    }

    if (error.response.data && error.response.data.message) {
      return Promise.reject(new Error(error.response.data.message));
    }

    return Promise.reject(error);
  },
);

type HttpGet<T, D> = typeof http.get<T, T, D>;

type HttpPost<T, D> = typeof http.post<T, T, D>;

type HttpPut<T, D> = typeof http.put<T, T, D>;

type HttpDelete<T, D> = typeof http.delete<T, T, D>;

// 这边通过将http的方法重新封装一遍，是为了于axios 库解耦，方便后续替换
const get = <T = any, D = any>(...arg: Parameters<HttpGet<T, D>>): ReturnType<HttpGet<T, D>> => http.get(...arg);
const post = <T = any, D = any>(...arg: Parameters<HttpPost<T, D>>): ReturnType<HttpPost<T, D>> => http.post(...arg);
const put = <T = any, D = any>(...arg: Parameters<HttpPut<T, D>>): ReturnType<HttpPut<T, D>> => http.put(...arg);
const del = <T = any, D = any>(...arg: Parameters<HttpDelete<T, D>>): ReturnType<HttpDelete<T, D>> =>
  http.delete(...arg);

export { del, get, post, put };
